package org.ala.shopping_test.shopping_center.repository.shard_key;

import org.ala.tiktools.sharddb.mybatis.router.shard_key_router.IShardKey;
import org.ala.tiktools.tools.list.Lists;
import org.ala.tiktools.tools.TimestampTools;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 订单原数据分片建
 * <p>  1000w 每天，如果都打到单表上是 115qps 的写。分12个库，单表qps可以打到10，匀点给其他事务都无压力
 * <p>  按订单id分库
 * <p>  按下单时间分表
 *
 * @author ala
 * @date 2025-03-19 15:29
 */
public class ShoppingOrderShardKey implements IShardKey {
    /**
     *  订单id
     *  <p> id为雪花id，[63, 23] 就是41位时间戳
     */
    protected Long id;
    /**
     *  订单id列表
     */
    protected List<Long> idIn;


    /**
     *  指明分库
     */
    protected String db;
    /**
     *  指明分库列表
     *  <p> id时间搜索条件会复制到每个分库上
     */
    protected List<String> dbs;


    /**
     *  时间戳
     */
    protected long timestamp = -1;
    /**
     *  与id一一对应
     */
    protected List<Long> timestampIdIn;
    /**
     *  下单时间戳范围（左右闭区间）
     */
    protected long timestampGte = -1, timestampLte = -1;



    public static ShoppingOrderShardKey build() {
        return new ShoppingOrderShardKey();
    }

    public ShoppingOrderShardKey copy() {
        return ShoppingOrderShardKey.build()
                .id(getId())
                .idIn(getIdIn())
                .db(getDb())
                .dbs(getDbs())
                .timestamp(getTimestamp())
                .timestampIdIn(getTimestampIdIn())
                .timestampGte(getTimestampGte()).timestampLte(getTimestampLte());
    }

    public String toString() {
        StringBuilder sbuf = new StringBuilder();
        sbuf.append("{type:ShoppingOrderShardKey");
        if (id != null) {sbuf.append(String.format(", id:%d", id));}
        if (!Lists.isEmpty(idIn)) {sbuf.append(String.format(", idIn:{%s}", idIn.stream().map(Object::toString).collect(Collectors.joining(","))));}
        if (timestamp >= 0) {sbuf.append(String.format(", timestamp:%d", timestamp));}
        if (timestampGte >= 0) {sbuf.append(String.format(", timestampGte:%d", timestampGte));}
        if (timestampLte >= 0) {sbuf.append(String.format(", timestampLte:%d", timestampLte));}
        return sbuf.append("}").toString();
    }


    public List<Long> getIdIn() {
        return idIn;
    }

    public void setIdIn(List<Long> idIn) {
        this.idIn = idIn;
    }

    public ShoppingOrderShardKey idIn(List<Long> idIn) {
        setIdIn(idIn);
        return this;
    }

    public ShoppingOrderShardKey idIn(Long id) {
        if (idIn == null) {idIn = new ArrayList<>();}
        if (id != null) {
            idIn.add(id);
        }
        return this;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public ShoppingOrderShardKey id(Long id) {
        setId(id);
        return this;
    }

    public String getDb() {
        return db;
    }

    public void setDb(String db) {
        this.db = db;
    }

    public ShoppingOrderShardKey db(String db) {
        setDb(db);
        return this;
    }

    public long getTimestampGte() {
        return timestampGte;
    }

    public void setTimestampGte(long timestampGte) {
        if (timestampGte < 0) {return;}
        this.timestampGte = timestampGte;
        if (timestampLte == -1) {
            timestampLte = timestampGte + TimestampTools.DAY_MS * 7;
        }
    }

    public ShoppingOrderShardKey timestampGte(long timestamp) {
        setTimestampGte(timestamp);
        return this;
    }

    public long getTimestampLte() {
        return timestampLte;
    }

    public void setTimestampLte(long timestampLte) {
        if (timestampLte < 0) {return;}
        this.timestampLte = timestampLte;
        if (timestampGte == -1) {
            timestampGte = timestampLte - TimestampTools.DAY_MS * 7;
        }
    }

    public ShoppingOrderShardKey timestampLte(long timestamp) {
        setTimestampLte(timestamp);
        return this;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    public ShoppingOrderShardKey timestamp(long timestamp) {
        setTimestamp(timestamp);
        return this;
    }

    public List<Long> getTimestampIdIn() {
        return timestampIdIn;
    }

    public void setTimestampIdIn(List<Long> timestampIdIn) {
        this.timestampIdIn = timestampIdIn;
    }

    public ShoppingOrderShardKey timestampIdIn(List<Long> timestampIdIn) {
        setTimestampIdIn(timestampIdIn);
        return this;
    }

    public ShoppingOrderShardKey timestampIdIn(Long timestamp) {
        if (timestampIdIn == null) {timestampIdIn = new ArrayList<>();}
        timestampIdIn.add(timestamp);
        return this;
    }

    public List<String> getDbs() {
        return dbs;
    }

    public void setDbs(List<String> dbs) {
        this.dbs = dbs;
    }

    public ShoppingOrderShardKey dbs(List<String> dbs) {
        setDbs(dbs);
        return this;
    }

    public ShoppingOrderShardKey dbs(String db) {
        if (dbs == null) {dbs = new ArrayList<>();}
        dbs.add(db);
        return this;
    }
}
